﻿using System;
using System.IO;
using System.Text;
using System.Web;

namespace down2.db
{
    public partial class down : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string fileName = "网易云音乐.exe";//客户端保存的文件名
            string filePath = "d:\\文件校验工具.exe";//路径          

            string fnUtf8 = Encoding.UTF8.GetString(Encoding.GetEncoding("gb2312").GetBytes(fileName));
            fnUtf8 = HttpUtility.UrlEncode(fileName);
            Response.ContentType = "application/octet-stream";
            Response.AddHeader("Content-Disposition", "attachment; filename=250/`^+副本.pdf");
            //设置文件编码。utf-8编码的中文需要使用urlencode转换。
            Response.AddHeader("Content-Type", "application/octet-stream;");
            Response.AddHeader("Pragma", "No-cache");
            Response.AddHeader("Cache-Control", "No-cache");
            Response.AddHeader("Expires", "0");

            Stream iStream = null;
            try
            {
                // Open the file.
                iStream = new System.IO.FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);

                // Total bytes to read:
                long blockSize = iStream.Length;
                long blockBegin = 0;
                long blockEnd = blockSize-1;
                long fileSize = blockSize;

                string range = Request.Headers.Get("Range");
                if (!string.IsNullOrEmpty(range))
                {
                    //清除bytes=
                    int pos = range.IndexOf("=");
                    if (pos != -1) range = range.Substring(pos + 1);

                    /*
                     * 1-
                     * -1
                     * 0-1
                     */
                    string[] indexs = range.Split("-".ToCharArray());
                    //-1
                    if (string.IsNullOrEmpty(indexs[0]))
                    {
                        blockSize = long.Parse(indexs[1]);
                        iStream.Seek(long.Parse(indexs[1]),SeekOrigin.End);
                        blockEnd = iStream.Length - 1;
                        blockBegin = iStream.Length - blockSize;
                    }//1-
                    else if (string.IsNullOrEmpty(indexs[1]))
                    {
                        iStream.Seek(long.Parse(indexs[0]),SeekOrigin.Begin);
                        blockSize = iStream.Length - long.Parse(indexs[0]);
                        blockBegin = long.Parse(indexs[0]);
                        blockEnd = (blockBegin + blockSize) - 1;
                    }//1-1
                    else
                    {
                        iStream.Seek(long.Parse(indexs[0]),SeekOrigin.Begin);
                        blockSize = (long.Parse(indexs[1]) - long.Parse(indexs[0])) + 1;
                        blockBegin = long.Parse(indexs[0]);
                        blockEnd = long.Parse(indexs[1]);
                    }
                }
                Response.AddHeader("Content-Range", string.Format("bytes {0}-{1}/{2}",blockBegin,blockEnd,fileSize));
                //if (blockSize > 1)
                //{
                //    Response.AddHeader("Content-Length", "100");
                //    blockSize = 100;
                //}
                //else
                //{
                    Response.AddHeader("Content-Length", blockSize.ToString());
                //}

                int buf_size = Math.Min(1048576, (int)blockSize);
                byte[] buffer = new Byte[buf_size];
                int length = 0;

                while (blockSize > 0 && Response.IsClientConnected)
                {
                    // Read the data in buffer.
                    length = iStream.Read(buffer, 0, buf_size);
                    length = (int)blockSize > length ? length : (int)blockSize;
                    blockSize -= length;

                    // Write the data to the current output stream.
                    Response.OutputStream.Write(buffer, 0, length);

                    // Flush the data to the HTML output.
                    Response.Flush();
                }
            }
            catch (Exception ex)
            {
                // Trap the error, if any.
                Response.Write("Error : " + ex.Message);
            }
            finally
            {
                if (iStream != null)
                {
                    //Close the file.
                    iStream.Close();
                }
            }
        }
        
        /// <summary>
        /// 为字符串中的非英文字符编码Encodes non-US-ASCII characters in a string.
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string ToHexString(string s)
        {
            char[] chars = s.ToCharArray();
            StringBuilder builder = new StringBuilder();
            for (int index = 0; index < chars.Length; index++)
            {
                bool needToEncode = NeedToEncode(chars[index]);
                if (needToEncode)
                {
                    string encodedString = ToHexString(chars[index]);
                    builder.Append(encodedString);
                }
                else
                {
                    builder.Append(chars[index]);
                }
            }
            return builder.ToString();
        }
        /// <summary>
        ///指定一个字符是否应该被编码 Determines if the character needs to be encoded.
        /// </summary>
        /// <param name="chr"></param>
        /// <returns></returns>
        private static bool NeedToEncode(char chr)
        {
            string reservedChars = "$-_.+!*'(),@=&";
            if (chr > 127)
                return true;
            if (char.IsLetterOrDigit(chr) || reservedChars.IndexOf(chr) >= 0)
                return false;
            return true;
        }
        /// <summary>
        /// 为非英文字符串编码Encodes a non-US-ASCII character.
        /// </summary>
        /// <param name="chr"></param>
        /// <returns></returns>
        private static string ToHexString(char chr)
        {
            UTF8Encoding utf8 = new UTF8Encoding();
            byte[] encodedBytes = utf8.GetBytes(chr.ToString());
            StringBuilder builder = new StringBuilder();
            for (int index = 0; index < encodedBytes.Length; index++)
            {
                builder.AppendFormat("%{0}", Convert.ToString(encodedBytes[index], 16));
            }
            return builder.ToString();
        }
    }
}